package com.fingard.dsp.bank.directbank.spdb01;


import com.fingard.dsp.bank.directbank.bankInterface.IBalance;
import com.fingard.dsp.bank.reqrespobj.balance.Req7505HisBalQry;
import com.fingard.dsp.bank.reqrespobj.balance.Req7506BalQry;
import com.fingard.dsp.bank.reqrespobj.balance.RetAts7505HisBalQry;
import com.fingard.dsp.bank.reqrespobj.balance.RetAts7506BalQry;
import com.fingard.dsp.bank.reqrespobj.balance.detail.RetAtsBalDetail;
import com.fingard.dsp.bank.reqrespobj.balance.detail.RetAtsHisBalDetail;
import com.fingard.text.StringHelper;
import com.fingard.xml.XmlTextReader;
import com.fingard.xml.XmlTextWriter;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class SPDB01Balance extends SPDB01Base implements IBalance {
    //单个余额查询和批量余额查询，统一采用流处理方式
    //1、循环调用Req7506BalQry.readRecord()读取一个请求明细，然后写入发银行的XML对象
    //2、发银行
    //3、循环调用XmlTextReader.read()读取一个银行返回节点，赋值返回ATS的明细对象，
    //   然后调用RetAts7506BalQry.writeRetDetail()，写入返回ATS的明细
    public RetAts7506BalQry d_7506_BalQry(Req7506BalQry p_req7506) throws Exception {//余额查询
        //余额查询返回ATS的对象
        RetAts7506BalQry retAts = new RetAts7506BalQry(p_req7506.reqHeader);
        retAts.writeStart();
        //拆分离岸户和非离岸户报文
        Map<String, Req7506BalQry> req7506QryMap = getReq7506QryMap(p_req7506);
        //分别请求
        for (Map.Entry<String, Req7506BalQry> map : req7506QryMap.entrySet()) {
            if ("1".equals(map.getKey())) {
                d_7506_BalQry_OSA(map.getValue(), retAts);//离岸账户余额
            } else if ("0".equals(map.getKey())) {
                d_7506_BalQry_NoOSA(map.getValue(), retAts);//非离岸账户余额
            }
        }
        retAts.writeEnd();
        return retAts;
    }

    private void d_7506_BalQry_OSA(Req7506BalQry p_req7506, RetAts7506BalQry retAts) throws Exception {
        String rspCode = "";
        String rspInfo = "";
        Map<String, String> mapRspBalance = new HashMap<String, String>();
        List<String> queryTransMasterIDList = new ArrayList<String>();
        while (p_req7506.readRecord()) {
            String queryTransMasterID = getBankConfig().getMapValueByKey("transMasterIDMapping", p_req7506.readedDetail.actNum);
            boolean isSame = false;
            for (int i = 0; i < queryTransMasterIDList.size(); i++) {
                if (queryTransMasterIDList.get(i).equals(queryTransMasterID)) {
                    isSame = true;
                    break;
                }
            }
            if (!isSame && !StringHelper.isNullOrEmpty(queryTransMasterID)) {
                queryTransMasterIDList.add(queryTransMasterID);
            }
        }
        p_req7506.resetReadMode();//重置
        try {
            for (int i = 0; i < queryTransMasterIDList.size(); i++) {
                int startNumber = 1;//查询起始数
                int totalNumber = 0;//总查询数
                while (startNumber == 1 || totalNumber >= startNumber) {
                    SPDB01Header tmpBnkHeader = new SPDB01Header();
                    tmpBnkHeader.transCode = "E103";
                    XmlTextWriter xmlWriter = new XmlTextWriter();//发银行报文的XML对象
                    xmlWriter.autoFormat = false;
                    xmlWriter.writeStartElement("body");
                    //根据传入的离岸账户查询对账户所属的离岸客户号，赋值到表体transMasterID中，否则不进行赋值
                    xmlWriter.writeElementString("transMasterID", queryTransMasterIDList.get(i));//备用字段
                    xmlWriter.writeElementString("beginNumber", startNumber + "");//查询起始数
                    xmlWriter.writeElementString("queryNumber", "20");//每次最大查询数
                    xmlWriter.writeEndElement();
                    xmlWriter.writeEndDocument();
                    String[] tmpRetBkStr = sendToBankOSA(xmlWriter.toXmlString(), tmpBnkHeader);
//                    String[] tmpRetBkStr = {"", "<?xml version=\"1.0\" encoding=\"gb2312\"?>\n" +
//                            "<packet><head><transCode>E103</transCode><signFlag>1</signFlag><packetID>2003121336130001</packetID><timeStamp>2020-03-12 13:36:13</timeStamp><returnCode>AAAAAAA</returnCode></head><body><totalNumber>2</totalNumber><lists name=\"LoopResult\"><list><acctNo>OSA11443632057567</acctNo><currency>14</currency><balance>1088611.54</balance><acctStatus>4</acctStatus></list><list><acctNo>OSA12743630234611</acctNo><currency>27</currency><balance>0.00</balance><acctStatus>4</acctStatus></list></lists></body></packet>"};
                    if (tmpRetBkStr[0].length() == 0) {
                        StringBuilder tmpSbMsg = new StringBuilder();
                        XmlTextReader tmpBkReader = loadBankRespXmlReader(tmpRetBkStr[1], tmpSbMsg);
                        if (tmpBkReader != null) {
                            String returnCode = tmpBkReader.getFirstTextNotNull("/packet/head/returnCode");
                            String returnMsg = tmpBkReader.getFirstTextNotNull("/packet/head/returnMsg");
                            if (StringHelper.isNullOrEmpty(returnMsg)) {
                                returnMsg = tmpBkReader.getFirstTextNotNull("/packet/body/returnMsg");
                            }
                            if (returnCode != null && returnCode.equals("AAAAAAA")) {
                                totalNumber = Integer.parseInt(tmpBkReader.getFirstTextNotNull("/packet/body/totalNumber"));//总数
                                while (tmpBkReader.read("/packet/body/lists/list")) {
                                    String key = tmpBkReader.readedXElement.getSingleTextNotNull("acctNo");//账号
                                    String value = tmpBkReader.readedXElement.getSingleTextNotNull("currency")
                                            + "_" + tmpBkReader.readedXElement.getSingleTextNotNull("balance");//币种_金额
                                    mapRspBalance.put(key, value);
                                }
                            } else {
                                rspCode = "-1";
                                rspInfo = returnMsg;
                            }
                        } else {
                            rspCode = "-1";
                            rspInfo = tmpSbMsg.toString();
                        }
                    } else {
                        rspCode = "-1";
                        rspInfo = tmpRetBkStr[1];
                    }
                    startNumber += 20;//不管实际返回多少，都加20（如果查询数20，而实际返回不到20，则说明到最后一页，或者系统异常）
                }
                //过滤非查询账户+币种
                if (mapRspBalance != null && mapRspBalance.size() > 0) {
                    while (p_req7506.readRecord()) {
                        String value = mapRspBalance.get(p_req7506.readedDetail.actNum);
                        if (StringHelper.hasAnyChar(value)) {
                            String cur = convertCurToATS(value.substring(0, value.indexOf("_")));
                            if (cur.equals(p_req7506.readedDetail.actCur)) {
                                RetAtsBalDetail tmpRetDetail = new RetAtsBalDetail();
                                tmpRetDetail.respCode = "0";
                                tmpRetDetail.actNum = p_req7506.readedDetail.actNum;
                                tmpRetDetail.actCur = cur;
                                tmpRetDetail.currBal = value.substring(value.indexOf("_") + "_".length()).replaceAll(",", "");
                                retAts.writeRetDetail(tmpRetDetail, p_req7506.isBatch);
                            } else {
                                rspCode = "-1";
                                rspInfo = "未查到账号信息";
                            }
                        } else {
                            rspCode = "-1";
                            rspInfo = "未查到账号信息";
                        }
                    }
                }
            }
        } catch (Exception e) {
            rspCode = "-1";
            rspInfo = e.getMessage();
        }
        if ("-1".equals(rspCode)) {
            if (!retAts.hasWrittenRespInfo) {
                retAts.writeRespCode(rspCode);
                retAts.writeRespInfo(rspInfo);
            }
        }
    }

    private void d_7506_BalQry_NoOSA(Req7506BalQry p_req7506, RetAts7506BalQry retAts) throws Exception {
        try {
            SPDB01Header tmpBnkHeader = new SPDB01Header();
            tmpBnkHeader.transCode = "4402";
            XmlTextWriter xmlWriter = new XmlTextWriter();//发银行报文的XML对象
            xmlWriter.autoFormat = false;
            xmlWriter.writeStartElement("body");
            xmlWriter.writeStartElementByAttr("lists", "<lists name=\"acctList\">");
            while (p_req7506.readRecord()) {
                xmlWriter.writeStartElement("list");
                xmlWriter.writeElementString("acctNo", p_req7506.readedDetail.actNum);
                xmlWriter.writeEndElement();
            }
            xmlWriter.writeEndDocument();
            String[] tmpRetBkStr = sendToBank(xmlWriter.toXmlString(), tmpBnkHeader);
            if (tmpRetBkStr[0].length() == 0) {
                StringBuilder tmpSbMsg = new StringBuilder();
                XmlTextReader tmpBkReader = loadBankRespXmlReader(tmpRetBkStr[1], tmpSbMsg);
                if (tmpBkReader != null) {
                    String returnCode = tmpBkReader.getFirstText("/packet/head/returnCode");
                    String returnMsg = tmpBkReader.getFirstText("/packet/head/returnMsg");
                    if (StringHelper.isNullOrEmpty(returnMsg)) {
                        returnMsg = tmpBkReader.getFirstText("/packet/body/returnMsg");
                    }
                    if (returnCode != null && returnCode.equals("AAAAAAA")) {
                        while (tmpBkReader.read("/packet/body/lists/list")) {
                            RetAtsBalDetail tmpRetDetail = new RetAtsBalDetail();

                            tmpRetDetail.respCode = "0";

                            tmpRetDetail.currBal = tmpBkReader.readedXElement.getSingleText("balance");
                            tmpRetDetail.availBal = tmpBkReader.readedXElement.getSingleText("canUseBalance");
                            tmpRetDetail.frozenBal = tmpBkReader.readedXElement.getSingleText("freezeBalance");

                            tmpRetDetail.actNum = tmpBkReader.readedXElement.getSingleText("acctNo");

                            retAts.writeRetDetail(tmpRetDetail, p_req7506.isBatch);
                        }
                    } else {
                        if (!retAts.hasWrittenRespInfo) {
                            retAts.writeRespCode("-1");
                            retAts.writeRespInfo(returnMsg);
                        }
                    }
                } else {
                    if (!retAts.hasWrittenRespInfo) {
                        retAts.writeRespCode("-1");
                        retAts.writeRespInfo(tmpSbMsg.toString());
                    }
                }
            } else {
                if (!retAts.hasWrittenRespInfo) {
                    retAts.writeRespCode("-1");
                    retAts.writeRespInfo(tmpRetBkStr[1]);
                }
            }
        } catch (Exception e) {
            if (!retAts.hasWrittenRespInfo) {
                retAts.writeRespCode("-1");
                retAts.writeRespInfo(e.getMessage());
            }
            //e.printStackTrace();
        }
    }

    @Override
    public RetAts7505HisBalQry d_7505_BalQry(Req7505HisBalQry p_req7505) throws Exception {
        RetAts7505HisBalQry retAts = new RetAts7505HisBalQry(p_req7505.reqHeader);
        String tmpRespCode = "";
        String tmpRespInfo = "";
        retAts.writeStart();//写返回ATS的统一头部信息
        try {
            SPDB01Header tmpBnkHeader = new SPDB01Header();
            tmpBnkHeader.transCode = "4403";
            XmlTextWriter xmlWriter = new XmlTextWriter();//发银行报文的XML对象
            xmlWriter.autoFormat = false;
            xmlWriter.writeStartElement("body");
            xmlWriter.writeElementString("acctNo", p_req7505.actNum);
            xmlWriter.writeElementString("beginDate", p_req7505.dateFrom);
            xmlWriter.writeElementString("endDate", p_req7505.dateTo);
            xmlWriter.writeEndElement();

            xmlWriter.writeEndDocument();
            String[] tmpRetBkStr = sendToBank(xmlWriter.toXmlString(), tmpBnkHeader);
            if (tmpRetBkStr[0].length() == 0) {
                StringBuilder tmpSbMsg = new StringBuilder();
                XmlTextReader tmpBkReader = loadBankRespXmlReader(tmpRetBkStr[1], tmpSbMsg);
                if (tmpBkReader != null) {
                    String returnCode = tmpBkReader.getFirstText("/packet/head/returnCode");
                    String returnMsg = tmpBkReader.getFirstText("/packet/head/returnMsg");
                    if (StringHelper.isNullOrEmpty(returnMsg)) {
                        returnMsg = tmpBkReader.getFirstText("/packet/body/returnMsg");
                    }
                    if (returnCode != null && returnCode.equals("AAAAAAA")) {
                        while (tmpBkReader.read("/packet/body/lists/list")) {
                            RetAtsHisBalDetail tmpRetDetail = new RetAtsHisBalDetail();
                            String tmpETYDAT = tmpBkReader.readedXElement.getSingleText("transDate");
                            if (tmpETYDAT.length() == 8) {
                                tmpRetDetail.balDate = tmpETYDAT.substring(0, 4) + "-" + tmpETYDAT.substring(4, 6) + "-" + tmpETYDAT.substring(6, 8);
                            } else {
                                tmpRetDetail.balDate = tmpETYDAT;
                            }
                            tmpRetDetail.actBal = tmpBkReader.readedXElement.getSingleText("balance");
                            retAts.writeRetDetail(tmpRetDetail);
                        }
                    } else {
                        tmpRespCode = "-1";
                        tmpRespInfo = returnMsg;
                    }
                } else {
                    tmpRespCode = "-1";
                    tmpRespInfo = tmpSbMsg.toString();
                }
            } else {
                tmpRespCode = "-1";
                tmpRespInfo = tmpRetBkStr[1];
            }

        } catch (Exception e) {
            tmpRespCode = "-1";
            tmpRespInfo = e.getMessage();
            e.printStackTrace();
        }
        if (tmpRespCode.equals("-1")) {
            retAts = new RetAts7505HisBalQry(p_req7505.reqHeader);
            retAts.writeStart();//写返回ATS的统一头部信息
            retAts.writeRespCode(tmpRespCode);
            retAts.writeRespInfo(tmpRespInfo);
        } else if (retAts.getWrittenRdCount() == 0) {
            retAts.writeRespCode("0");
            retAts.writeRespInfo("返回结果为空，所查询时间段内不存在历史余额");
        }
        retAts.writeEnd();
        return retAts;
    }

}
